Ahora que hemos visto qué es un cuaderno Jupyter, es hora de ver cómo se utilizan en la práctica, lo que nos permitirá entender mejor por qué son tan populares.
Para ello vamos a usar un conjunto de datos sobre las 'Personas emigrantes por continente de nacionalidad, sexo y edad quinquenal Población Demografía', tomado de Open Data BCN
import pandas as pd # Librería para el procesamiento de los datos usando pandas dataframes
import matplotlib.pyplot as plt # Libería de visualización de datos
import seaborn as sns # Libería de visualización de datos avanzada
sns.set(style="darkgrid") # Establecer el estilo de las gráficas
# Leer datos
dataframe = pd.read_csv('data/2022_pad_emi_mdbas_sexe_edat-q_continent.csv', encoding='utf-8')
# Imprimir las primeras filas
dataframe.head()
| Any | Codi_Districte | Nom_Districte | Codi_Barri | Nom_Barri | AEB | Seccio_Censal | Valor | NACIONALITAT_CONTINENT | EDAT_Q | SEXE | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2022 | 1 | Ciutat Vella | 1 | el Raval | 1 | 1001 | .. | 1 | 4 | 1 |
| 1 | 2022 | 1 | Ciutat Vella | 1 | el Raval | 1 | 1001 | .. | 1 | 5 | 1 |
| 2 | 2022 | 1 | Ciutat Vella | 1 | el Raval | 1 | 1001 | .. | 1 | 5 | 2 |
| 3 | 2022 | 1 | Ciutat Vella | 1 | el Raval | 1 | 1001 | .. | 1 | 7 | 2 |
| 4 | 2022 | 1 | Ciutat Vella | 1 | el Raval | 1 | 1001 | .. | 2 | 5 | 1 |
# Imprimir las 6 últimas filas
dataframe.tail(n=6)
| Any | Codi_Districte | Nom_Districte | Codi_Barri | Nom_Barri | AEB | Seccio_Censal | Valor | NACIONALITAT_CONTINENT | EDAT_Q | SEXE | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 34217 | 2022 | 10 | Sant Martí | 73 | la Verneda i la Pau | 233 | 10143 | .. | 4 | 13 | 1 |
| 34218 | 2022 | 10 | Sant Martí | 73 | la Verneda i la Pau | 233 | 10143 | .. | 4 | 13 | 2 |
| 34219 | 2022 | 10 | Sant Martí | 73 | la Verneda i la Pau | 233 | 10143 | .. | 4 | 16 | 1 |
| 34220 | 2022 | 10 | Sant Martí | 73 | la Verneda i la Pau | 233 | 10143 | .. | 4 | 17 | 1 |
| 34221 | 2022 | 10 | Sant Martí | 73 | la Verneda i la Pau | 233 | 10143 | .. | 4 | 18 | 1 |
| 34222 | 2022 | 10 | Sant Martí | 73 | la Verneda i la Pau | 233 | 10143 | .. | 4 | 18 | 2 |
dataframe['SEXE'][1:10]
1 1 2 2 3 2 4 1 5 2 6 2 7 1 8 1 9 2 Name: SEXE, dtype: int64
# Crear un diccionario de mapeo para reemplazar los valores
mapeo = {1: 'mujer', 2: 'hombre'}
# Aplicar el reemplazo a la columna "sexo"
dataframe['SEXE'] = dataframe['SEXE'].replace(mapeo)
# Volver a visualizar el dataframe
dataframe['SEXE'].unique()
array(['mujer', 'hombre'], dtype=object)
# Imprimir longitud
filas = len(dataframe)
print("Número de registros", filas)
columnas = len(dataframe.columns)
print("Número de columnas", columnas)
print(f"El DataFrame tiene {filas} filas y {columnas} columnas.")
Número de registros 34223 Número de columnas 11 El DataFrame tiene 34223 filas y 11 columnas.
# Imprimir longitud
filas = dataframe.shape[0]
print("Número de registros", filas)
columnas = dataframe.shape[1]
print("Número de columnas", columnas)
print(f"El DataFrame tiene {filas} filas y {columnas} columnas.")
Número de registros 34223 Número de columnas 11 El DataFrame tiene 34223 filas y 11 columnas.
print("info", dataframe.info(verbose=False))
<class 'pandas.core.frame.DataFrame'> RangeIndex: 34223 entries, 0 to 34222 Columns: 11 entries, Any to SEXE dtypes: int64(7), object(4) memory usage: 2.9+ MB info None
# Summary del dataframee
dataframe.describe()
| Any | Codi_Districte | Codi_Barri | AEB | Seccio_Censal | NACIONALITAT_CONTINENT | EDAT_Q | |
|---|---|---|---|---|---|---|---|
| count | 34223.0 | 34223.000000 | 34223.000000 | 34223.000000 | 34223.000000 | 34223.000000 | 34223.000000 |
| mean | 2022.0 | 5.555445 | 32.232358 | 116.198726 | 5616.142244 | 3.785904 | 7.370862 |
| std | 0.0 | 3.017504 | 22.373010 | 67.272176 | 3019.200606 | 20.155126 | 4.300633 |
| min | 2022.0 | 1.000000 | 1.000000 | 1.000000 | 1001.000000 | 1.000000 | 0.000000 |
| 25% | 2022.0 | 3.000000 | 11.000000 | 57.000000 | 3015.000000 | 3.000000 | 5.000000 |
| 50% | 2022.0 | 6.000000 | 28.000000 | 116.000000 | 6009.000000 | 4.000000 | 7.000000 |
| 75% | 2022.0 | 8.000000 | 52.000000 | 175.000000 | 8091.000000 | 4.000000 | 10.000000 |
| max | 2022.0 | 10.000000 | 73.000000 | 233.000000 | 10237.000000 | 999.000000 | 20.000000 |
# Visualizar los tipos
dataframe.dtypes
Any int64 Codi_Districte int64 Nom_Districte object Codi_Barri int64 Nom_Barri object AEB int64 Seccio_Censal int64 Valor object NACIONALITAT_CONTINENT int64 EDAT_Q int64 SEXE object dtype: object
dataframe.columns = ['any', 'codi_districte', 'nom_districte', 'codi_barri', 'nom_barri', 'aeb', 'seccio_censal', 'valor', 'nacionalitat_continent', 'edat_quinquenal', 'sexe']
dataframe.columns
Index(['any', 'codi_districte', 'nom_districte', 'codi_barri', 'nom_barri',
'aeb', 'seccio_censal', 'valor', 'nacionalitat_continent',
'edat_quinquenal', 'sexe'],
dtype='object')
# Establecer el tamaño de la figura
plt.figure(figsize=(15, 7))
# Crear historgrama
plt.hist(dataframe['nom_districte'], bins=len(dataframe['nom_districte'].unique()), edgecolor='k')
# Personalizar la gráfica, añadiendo etiquetas y título
plt.xlabel('Distrito')
plt.ylabel('Frecuencia')
plt.title('Histograma del número de personas por distrito')
# Imprimir el histograma
plt.show()
# Calcular la edad media por distrito
edad_media_por_distrito = dataframe.groupby('nom_districte')['edat_quinquenal'].mean().reset_index()
# Establecer el tamaño de la figura
plt.figure(figsize=(16, 7))
# Crear el gráfico de barras
plt.scatter(edad_media_por_distrito['nom_districte'], edad_media_por_distrito['edat_quinquenal'])
# Etiquetas y título
plt.xlabel('Distrito')
plt.ylabel('Edad Media')
plt.title('Edad Quinquenal Media por Distrito')
# Mostrar el gráfico
plt.show()
# Crear una figura con dos subplots
fig, axs = plt.subplots(1, 2, figsize=(12, 6)) # 1 fila, 2 columnas
# Subplot 1: Diagrama circular para el número de personas por sexo
sexo_counts = dataframe['sexe'].value_counts()
axs[0].pie(sexo_counts, labels=sexo_counts.index, autopct='%1.1f%%', startangle=90)
axs[0].set_title('Número de Personas por Sexo')
# Subplot 2: Diagrama circular para el campo "nacionalitat_continent"
nacionalidad_counts = dataframe['nacionalitat_continent'].value_counts()
axs[1].pie(nacionalidad_counts, labels=nacionalidad_counts.index, autopct='%1.1f%%', startangle=90)
axs[1].set_title('Nacionalidad por Continente')
# Ajustar el espacio entre subplots
plt.tight_layout()
# Mostrar los subplots
plt.show()
dataframe_numeric = dataframe[['any', 'codi_districte', 'codi_barri', 'seccio_censal']]
# Calcular la matriz de correlación
correlation_matrix = dataframe_numeric.corr()
# Establecer el tamaño de la figura
plt.figure(figsize=(10, 8))
# Crear el heatmap
sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm', linewidths=0.5)
# Añadir el título
plt.title('Mapa de Calor de Correlación entre Variables Numéricas')
# Graficar
plt.show()
# Establecer el tamaño de la figura
plt.figure(figsize=(12, 8))
# Crear grafico agrupando por 'nom_districte' y
sns.countplot(data=dataframe, x='nom_districte', hue='nacionalitat_continent')
# HUE: se utiliza para diferenciar y
#codificar por colores las barras del gráfico en función de los valores de una variable categórica.
# Rotar las etiquetas
plt.xticks(rotation=90)
# Establecer nombres para eje X y eje y
plt.xlabel('Distrito')
plt.ylabel('Recuento')
# Establecer título
plt.title('Distribución de Nacionalidades por Distrito')
# Establecer título de la leyenda
plt.legend(title='Nacionalidad')
# Graficar
plt.show()
!pip install plotly
Requirement already satisfied: plotly in /opt/conda/lib/python3.9/site-packages (5.17.0) Requirement already satisfied: packaging in /opt/conda/lib/python3.9/site-packages (from plotly) (20.9) Requirement already satisfied: tenacity>=6.2.0 in /opt/conda/lib/python3.9/site-packages (from plotly) (8.2.3) Requirement already satisfied: pyparsing>=2.0.2 in /opt/conda/lib/python3.9/site-packages (from packaging->plotly) (2.4.7)
import plotly.express as px
# Calcular la edad media por distrito
edad_media_por_distrito = dataframe.groupby('nom_districte')['edat_quinquenal'].mean().reset_index()
# Crear un gráfico de dispersión interactivo con Plotly Express
fig = px.scatter(edad_media_por_distrito, x='nom_districte', y='edat_quinquenal', title='Gráfico de Dispersión Interactivo')
fig.show()
dataframe['nom_districte'].unique()
array(['Ciutat Vella', 'Eixample', 'Sants-Montjuïc', 'Les Corts',
'Sarrià-Sant Gervasi', 'Gràcia', 'Horta-Guinardó', 'Nou Barris',
'Sant Andreu', 'Sant Martí'], dtype=object)
!pip install folium
Requirement already satisfied: folium in /opt/conda/lib/python3.9/site-packages (0.14.0) Requirement already satisfied: branca>=0.6.0 in /opt/conda/lib/python3.9/site-packages (from folium) (0.6.0) Requirement already satisfied: jinja2>=2.9 in /opt/conda/lib/python3.9/site-packages (from folium) (3.0.1) Requirement already satisfied: numpy in /opt/conda/lib/python3.9/site-packages (from folium) (1.20.3) Requirement already satisfied: requests in /opt/conda/lib/python3.9/site-packages (from folium) (2.31.0) Requirement already satisfied: MarkupSafe>=2.0 in /opt/conda/lib/python3.9/site-packages (from jinja2>=2.9->folium) (2.0.1) Requirement already satisfied: urllib3<3,>=1.21.1 in /opt/conda/lib/python3.9/site-packages (from requests->folium) (1.26.5) Requirement already satisfied: certifi>=2017.4.17 in /opt/conda/lib/python3.9/site-packages (from requests->folium) (2021.5.30) Requirement already satisfied: idna<4,>=2.5 in /opt/conda/lib/python3.9/site-packages (from requests->folium) (2.10) Requirement already satisfied: charset-normalizer<4,>=2 in /opt/conda/lib/python3.9/site-packages (from requests->folium) (3.3.0)
import folium
# Crear un mapa de Barcelona centrado en coordenadas específicas
barcelona_map = folium.Map(location=[41.3851, 2.1734], zoom_start=12)
# Lista de distritos
distritos = ['Ciutat Vella', 'Eixample', 'Sants-Montjuïc', 'Les Corts',
'Sarrià-Sant Gervasi', 'Gràcia', 'Horta-Guinardó', 'Nou Barris',
'Sant Andreu', 'Sant Martí']
# Coordenadas aproximadas de los distritos (puedes ajustar estas coordenadas)
coordenadas = {
'Ciutat Vella': [41.3786, 2.1924],
'Eixample': [41.3917, 2.1649],
'Sants-Montjuïc': [41.3726, 2.1546],
'Les Corts': [41.3835, 2.1174],
'Sarrià-Sant Gervasi': [41.3971, 2.1354],
'Gràcia': [41.4024, 2.1575],
'Horta-Guinardó': [41.4364, 2.1468],
'Nou Barris': [41.4417, 2.1767],
'Sant Andreu': [41.4354, 2.1897],
'Sant Martí': [41.4181, 2.1993]
}
# Iterar sobre los distritos y agregar marcadores al mapa
for distrito in distritos:
folium.Marker(location=coordenadas[distrito], popup=distrito).add_to(barcelona_map)
# Mostrar el mapa interactivo
barcelona_map
# Agregar conexiones (líneas) entre marcadores
connections = [
('Ciutat Vella', 'Eixample'),
('Eixample', 'Sants-Montjuïc'),
('Sants-Montjuïc', 'Les Corts'),
('Les Corts', 'Sarrià-Sant Gervasi'),
('Sarrià-Sant Gervasi', 'Gràcia'),
('Gràcia', 'Horta-Guinardó'),
('Horta-Guinardó', 'Nou Barris'),
('Nou Barris', 'Sant Andreu'),
('Sant Andreu', 'Sant Martí'),
('Sant Martí', 'Ciutat Vella'),
]
for connection in connections:
distrito_a, distrito_b = connection
coord_a = coordenadas[distrito_a]
coord_b = coordenadas[distrito_b]
folium.PolyLine([coord_a, coord_b], color='blue').add_to(barcelona_map)
# Mostrar el mapa interactivo
barcelona_map